#ifndef THREAD_HPP
#define THREAD_HPP

#include <iostream>
#include <pthread.h>
#include <functional>
#include <string>
#include <unistd.h>

namespace threadmodule
{
    static int i = 1;
    using func_t = std::function<void(std::string name)>;
    enum class STATUS
    {
        NEW,
        START,
        STOP
    };
    class thread
    {
        static void *routine(void *arg)
        {
            thread *obj = static_cast<thread *>(arg);
            std::cout << obj->_name << "is runing" << std::endl;
            obj->_func(obj->name());
            return nullptr;
        }

    public:
        thread(func_t func) : _id(getpid()), _func(func), is_joined(true), _status(STATUS::NEW)
        {
            _name = "thread-" + std::to_string(i++);
        }
        bool start()
        { // 开始线程
            if (_status != STATUS::START)
            {
                int n = pthread_create(&_tid, nullptr, routine, this);
                if (n != 0)
                {
                    return false;
                }
                _status = STATUS::START;
                std::cout << _name << ":is start" << std::endl;
                return true;
            }
            return false;
        }
        bool cancel()
        { // 删除线程
            if (_status == STATUS::START)
            {
                int n = pthread_cancel(_tid);
                if (n != 0)
                {
                    return false;
                }
                std::cout << _name << ":is stop" << std::endl;
                _status = STATUS::STOP;
                return true;
            }
            return false;
        }
        bool join()
        { // 回收线程
            if (is_joined == false)
                return false;
            if (_status == STATUS::STOP)
            {
                int n = pthread_join(_tid, nullptr);
                if (n != 0)
                {
                    return false;
                }
                std::cout << _name << ":is join success" << std::endl;
                return true;
            }
            return false;
        }
        void detach()
        { // 修改线程属性
            if (is_joined == false)
                return;
            if (pthread_detach(_tid) == 0)
                is_joined = false;
        }
        std::string name() { return _name; }

    private:
        pthread_t _tid;
        pid_t _id;
        STATUS _status;
        bool is_joined;
        std::string _name;
        func_t _func;
    };
}

#endif
